iT邦幫忙

0

筆記|React - 7 - 有條件的渲染

Kim 2023-04-10 23:10:08774 瀏覽
  • 分享至 

  • xImage
  •  

☁️ 開場

開發時,畫面往往需要根據情境來呈現,在 React 我們可以運用 JavaScript 去撰寫邏輯,判斷在什麼樣的條件下,要渲染哪個 JSX!

這篇筆記主要整理自:官方文件 Conditional Rendering
示範情境同官方文件:我們要製作一個打包清單,確認打包的會出現一個小打勾,還沒打包的就沒有

function Item({ name, isPacked }) {
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Hat" 
        />
        <Item 
          isPacked={false} 
          name="Phone" 
        />
      </ul>
    </section>
  );
}


🔠 if/else statement

常用情境:有兩種以上渲染情境時

function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name} ✔</li>;
  }
  
  return <li className="item">{name}</li>;
}

翻譯蒟蒻:如果 isPacked 為 true,就回傳有打勾的<li>,當 isPacked 為 false,就會略過上面的 return,回傳沒有打勾的<li>


🆎 conditional/ternary operator 條件/三元運算子 ?:

常用情境:有兩種渲染情境時

第一種寫法,類 if/else

function Item({ name, isPacked }) {
  return isPacked ?  <li className="item">{name} ✔</li> : <li className="item">{name}</li>;
}

翻譯蒟蒻:同 if/else,如果 isPacked 為 true,就回傳前面有打勾的<li>,當 isPacked 為 false,就會回傳後面沒有打勾的<li>

第二種寫法

寫第一種寫法時會覺得一直在重複,我們可以鎖定:兩邊的差異下手即可,因為 JS 可以用在 JSX 裡!

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? name + ' ✔' : name}
    </li>
  );
}

翻譯蒟蒻:如果 isPacked 為 true,就回傳「name + 打勾」,為 false,就回傳「name」

🤔 延伸思考:if 的寫法,和第二種 conditional operator 的寫法完全等價?

用 object-oriented programming 的角度來思考,可能會覺得 if 的寫法會創造出兩種不一樣的 <li> instance,但 JSX 不是 instance,只是描述 UI 結構的一種方式,它們並非真正的 DOM node,所以上面兩種寫法是完全等價的。(更完整的敘述可以參考文件的這一 part,筆者此處暫時還沒有理解的非常徹底,歡迎大家分享對文件這段的理解,一起交流)


🅰️ logical operator 邏輯運算子 &&

常用情境:在某個情況為 true 時要渲染東西,否則不要渲染任何東西

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

翻譯蒟蒻:如果 isPacked 為 true,就印出「打勾」,為 false 就不印任何東西

補充:&& 的運作模式

  • 當左邊是 true 的時候 return 右邊的值
  • 當左邊是 false 的時候,整體的 expression 會變成 false,React 把 false 當成 JSX tree 的「洞」,就像 null or undefined,就不會印出任何東西
  • 唯獨 0 雖然為 falsy value ,但會被印出來!
  • 所以在使用 && 的時候盡量不要在左邊放數字
    • 陷阱情境:messageCount && <p>New messages</p>.
      messageCount為 0 的時候,容易以為這樣寫會什麼都沒有印,但實際上會印出 0
    • 避開陷阱:讓左邊呈現布林值 messageCount > 0 && <p>New messages</p>.

➕ 利用變數存放 JSX

有時回傳值會是大量的 JSX,這時可以利用變數存放回傳的 JSX,保持 markup 的清爽

舉例:將要渲染的 JSX 存放在 itemContent 變數中
function Item({ name, isPacked }) {
  let itemContent = name;

  if (isPacked) {
	// 使用變數存放 JSX
    itemContent = (
      <del>
        {name + " ✔"}
      </del>
    );
  }

  // 這邊的 markup 就會很清爽
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}


💃🏻 總結

以下為官方文件的 Recap,不做翻譯,只畫重點

  • In React, you control branching logic with JavaScript.
  • You can return a JSX expression conditionally with an if statement.
  • You can conditionally save some JSX to a variable and then include it inside other JSX by using the curly braces.
  • In JSX, {cond ? <A /> : <B />} means “if cond, render <A />, otherwise <B />.
  • In JSX, {cond && <A />} means “if cond, render <A />, otherwise nothing”.
  • The shortcuts are common, but you don’t have to use them if you prefer plain if.

以上,有任何想法或文內有誤、不清楚歡迎提出,謝謝大家 🙏🏻
.
筆者小記:能用 JS 邏輯判斷要渲染什麼只會讓我更愛 React xd


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言